open Hw1
module CharMap = Map.Make(Char)

let print_list l =
  print_endline (String.concat " " (List.map string_of_int l))

let print_pairs l =
 List.iter (fun (x,n) -> print_int x ;
                         print_string " ";
                         print_int n ; print_newline () ) l

let compare_rle l =
  print_string "Initial: ";
  print_list l;
  print_endline "Result:";
  print_pairs (rle l)

let compare_tt s =
  print_endline ("Initial: " ^ s); 
  print_endline "Result:";
  print_endline (string2tt s)

let compare_fv s =
  let expr = string2expr s in
  let vars = free_vars expr in
  print_endline (s ^ " : " ^ String.concat " " (List.map (String.make 1) vars))

let ppenv env =
 CharMap.fold (fun c b l -> l ^ String.make 1 c ^ ":" ^ string_of_bit b ^ " ")
    env ""

let compare_eval pairs s =
  let expr = string2expr s in
  let env = List.fold_left (fun m (v, b) -> CharMap.add v b m)
                              CharMap.empty pairs in
  print_endline (s ^ " " ^ ppenv env ^ " " ^ (string_of_bit (eval env expr)))
  
let _ = 
  print_endline "RLE tests" ;
  compare_rle [1;1;1;3;5;5;3;3;1] ;
  compare_rle [] ;
  compare_rle [1];
  compare_rle [1;1];
  compare_rle [1;1;1];
  compare_rle [1;2;3;1;1;1;2;2;3;3;1] ;
  print_endline "free_vars tests" ;
  compare_fv "A + B" ;
  compare_fv "B + A" ;
  compare_fv "A + B + BC" ;
  compare_fv "(B + D)(D + !(AE))(D + B)";
  print_endline "eval tests" ;
  compare_eval [('A',true); ('B',false)] "A + B" ;
  compare_eval [('A',true); ('B',false)] "A + !B" ;
  compare_eval [('A',true); ('B',false)] "!A + B" ;
  compare_eval [('A',true); ('B',false)] "AB" ;
  compare_eval [('A',true); ('B',false)] "A!B" ;
  print_endline "Truth Table tests" ;
  compare_tt "(A+B)(!A+!B)(A!B+A)";
  compare_tt "(A+B)(C+!D)"
 
